package cnt5106.p2p.peer.filesystem;


import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;


public class FileControler 
{
	public ChunkList chunkList = null;
	private File file =null;
	long fileLength = 0;
	
	public FileControler(String path)
	/// create a FileControler of an existing file. Used by file owner.
	{
		file = new File(path);
		if(!file.exists())
		{
			System.out.println("File not exist!");
			System.exit(1);
		}
		fileLength = file.length();
		chunkList = new ChunkList(fileLength);
	}
	
	public FileControler(String path, long fileLength) throws IOException
	/// create a new file of given size. Used by peer.
	{
		this.fileLength = fileLength;
		RandomAccessFile rFile = new RandomAccessFile(path, "rw");
        rFile.setLength(fileLength);      // create a new file with size of fileLength
        rFile.close();
        file = new File(path);
        chunkList = new ChunkList(fileLength);
	}
	
	//********* Test *********//
	public void testPrintChunkList()
	{
		for (int i=0; i<chunkList.getLength(); i++)
			if (chunkList.checkChunk(i))
				System.out.print(i + ",");
	}
	//************************//
	
	public int emptySlot()
	{
		return chunkList.getEmptyChunk();
	}
	
	public boolean isFinished()
	{
		return chunkList.isFinished();
	}
	
	public int chunkNum()
	{
		return chunkList.getLength();
	}
	
	public synchronized byte[] readFile(int indx, boolean fileOwner) throws IOException
    {
		if (!chunkList.checkChunk(indx) && !fileOwner)
			return null;
		else
		{
			//System.out.println(Thread.currentThread().getName() + " reading");
			int buffSize = (int) (((fileLength - indx*100*1024) > 102400) ? 102400 : (fileLength - indx*100*1024));
	        byte[] buff = new byte[buffSize];

	        if ((indx < 0) || (indx > chunkList.getLength()))
	        {
	            System.out.println("The requested block exceeds the range of the file.");
	            System.exit(1);
	        }
	        
	        RandomAccessFile rFile = new RandomAccessFile(file, "r");
	        rFile.seek(indx * 100 * 1024);
	        rFile.read(buff);
	        rFile.close();
	        
	        if (fileOwner)
	        	chunkList.setChunk(indx);  // 
	        //System.out.println(Thread.currentThread().getName() + " finish reading");
	        return buff;
		}		
    }
	
	
	public synchronized void writeFile(byte[] data, int indx) throws IOException
    {
        if (!chunkList.checkChunk(indx))
        {
        	//System.out.println(Thread.currentThread().getName() + " writing");
            if (indx > chunkList.getLength())
            {
                System.out.println("The requested block exceeds the range of the file.");
                System.exit(1);
            }
        	RandomAccessFile rFile = new RandomAccessFile(file, "rw");
            rFile.seek(indx * 100 * 1024);
            rFile.write(data, 0, data.length);
            rFile.close();
            
            chunkList.setChunk(indx);
            //System.out.println(Thread.currentThread().getName() + "finish writing");
        }
    }
}
